/******************************************************************************
 *      Mestrado em Ciencia da Computacao - UFMS
 *		Redes de Computadores - Prof. Dr. Ronaldo Alves Ferreira
 *		Alunos: Geraldo Landre, Marcel Tolentino, Vinicius Bueno
 *****************************************************************************/
/* tcp.h - TCP_HLEN, SEQCMP */

#ifndef TCP_H
#define TCP_H

#include "ether.h"
//#include "ip.h"
#include "udp.h"

typedef long tcpseq;

/*
	SEQCMP - sequence space comparator
		This handles sequence space wrap-around.
	Overlow/Underflow makes the result below correct ( -, 0, +)
	for any a, b in the sequence space.
	Results:
		result	implies
		  -	 a < b
		  0	 a = b
		  +	 a > b

*/

#define SEQCMP(a,b)	((a) - (b))


/* TCP Control Bits */

#define TCPF_URG	0x20	/*urgent pointer is valid */
#define TCPF_ACK	0x10	/*acknowledgment field is valid */
#define TCPF_PSH	0x08	/* this segment request a push */
#define TCPF_RST	0x04	/*reset the connection */
#define TCPF_SYN	0x02	/* synchronize sequence numbers */
#define TCPF_FIN	0x01	/*sender has reached end of its stream */

#define TCPMHLEN	20	/*minimum TCP header length */
#define TCPHOFFSET	0x50	/* tcp_offset value for TCPMHLEN */
#define TCP_HLEN(ptcp)	(((ptcp)->tcp_offset & 0xf0)>>2)

/*TCP Options */

#define TPO_EOOL	0	/*enf od Option List */
#define TPO_NOOP	1	/* no Operation */
#define TPO_MSS		2	/* maximum Segment Size */

/* tcp packet format */

#define TCPPKTLEN 4288
#define TCPDATALEN (TCPPKTLEN - TCPMHLEN)
struct tcp
{
    unsigned short tcp_sport;	/*source port */
    unsigned short tcp_dport;	/*destination port */
    tcpseq tcp_seq;			/*sequence */
    tcpseq tcp_ack;			/*acknowledged sequence */
    unsigned char tcp_offset;
    unsigned char tcp_code;		/*control flags */
    unsigned short tcp_window;	/* window advertisement */
    unsigned short tcp_cksum;	/* check sum */
    unsigned short tcp_urgptr;	/* urgent pointer */
    unsigned char tcp_data[TCPDATALEN]; // 4288 - 20 --> 536 octetos - cabecalho
}__attribute__((__packed__));

struct udp
{
    ipaddr ip_src;
    ipaddr ip_dst;
    u_short udp_len;
    //struct tcp udp_data;
    u_char udp_data[TCPPKTLEN];
};

int input_thread, output_thread, timer_thread, udp_thread;

int tcpxmit (int, int);
unsigned short tcpcksum (struct udp*, unsigned);
struct tcp *tcpnet2h(struct tcp *), *tcph2net (struct tcp *);
int tcpreset(struct udp *pudpin);
int tcpsend (int, int);
int tcpiss (void);
int tcprexmt (int,int);
int tcpwr (int, u_char *, unsigned, int);

#endif
